package cn.cjx.system.service.impl;

import cn.cjx.basic.annotation.PreAuthorize;

import cn.cjx.basic.utils.Classutil;
import cn.cjx.system.domain.Permission;
import cn.cjx.system.mapper.PermissionMapper;
import cn.cjx.system.service.IPermissionScanService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.io.FileFilter;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author: cjx
 * @Date: 2022/5/15
 */
@Service
public class PermissionScanServiceImpl implements IPermissionScanService {
	@Autowired
	private PermissionMapper permissionMapper;

	private static final String PKG_PREFIX = "cn.cjx.";
	private static final String PKG_SUFFIX = ".controller";

	@Override
	public void permissionScan() {

		//获取org.yaosang下面所有的模块目录
		String path = this.getClass().getResource("/").getPath() + "/cn/cjx/";
		File file = new File(path);
		File[] files = file.listFiles(new FileFilter() {
			@Override
			public boolean accept(File file) {
				return file.isDirectory();
			}
		});

		//获取org.yaosang.*.web.controller里面所有的类
		Set<Class> clazzes = new HashSet<>();
		for (File fileTmp : files) {
			System.out.println(fileTmp.getName());
			clazzes.addAll(Classutil.getClasses(PKG_PREFIX + fileTmp.getName() + PKG_SUFFIX));
		}

		for (Class clazz : clazzes) {
			Method[] methods = clazz.getMethods();
			if (methods == null || methods.length < 1)
				return;
			for (Method method : methods) {
				String uri = getUri(clazz, method);
				try {
					PreAuthorize preAuthorizeAnno = method.getAnnotation(PreAuthorize.class);
					if (preAuthorizeAnno == null)
						continue;
					String name = preAuthorizeAnno.name();
					String permissionSn = preAuthorizeAnno.value();
					Permission permissionTmp = permissionMapper.loadBySn(permissionSn);
					//如果不存在就添加
					if (permissionTmp == null) {
						Permission permission = new Permission();
						permission.setName(name);
						permission.setSn(permissionSn);
						permission.setUrl(uri);
						permissionMapper.save(permission);
					} else {
						//如果不存在就修改
						permissionTmp.setName(name);
						permissionTmp.setSn(permissionSn);
						permissionTmp.setUrl(uri);
						permissionMapper.update(permissionTmp);
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

	private String getUri(Class clazz, Method method) {
		String classPath = "";
		Annotation annotation = clazz.getAnnotation(RequestMapping.class);
		if (annotation != null) {
			RequestMapping requestMapping = (RequestMapping) annotation;
			String[] values = requestMapping.value();
			if (values != null && values.length > 0) {
				classPath = values[0];
				if (!"".equals(classPath) && !classPath.startsWith("/"))
					classPath = "/" + classPath;
			}
		}
		GetMapping getMapping = method.getAnnotation(GetMapping.class);
		String methodPath = "";
		if (getMapping != null) {
			String[] values = getMapping.value();
			if (values != null && values.length > 0) {
				methodPath = values[0];
				if (!"".equals(methodPath) && !methodPath.startsWith("/"))
					methodPath = "/" + methodPath;
			}
		}
		PostMapping postMapping = method.getAnnotation(PostMapping.class);
		if (postMapping != null) {
			String[] values = postMapping.value();
			if (values != null && values.length > 0) {
				methodPath = values[0];
				if (!"".equals(methodPath) && !methodPath.startsWith("/"))
					methodPath = "/" + methodPath;
			}
		}
		DeleteMapping deleteMapping = method.getAnnotation(DeleteMapping.class);
		if (deleteMapping != null) {
			String[] values = deleteMapping.value();
			if (values != null && values.length > 0) {
				methodPath = values[0];
				if (!"".equals(methodPath) && !methodPath.startsWith("/"))
					methodPath = "/" + methodPath;
			}
		}
		PutMapping putMapping = method.getAnnotation(PutMapping.class);
		if (putMapping != null) {
			String[] values = putMapping.value();
			if (values != null && values.length > 0) {
				methodPath = values[0];
				if (!"".equals(methodPath) && !methodPath.startsWith("/"))
					methodPath = "/" + methodPath;
			}

		}
		PatchMapping patchMapping = method.getAnnotation(PatchMapping.class);
		if (patchMapping != null) {
			String[] values = patchMapping.value();
			if (values != null && values.length > 0) {
				methodPath = values[0];
				if (!"".equals(methodPath) && !methodPath.startsWith("/"))
					methodPath = "/" + methodPath;
			}
		}
		RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
		if (requestMapping != null) {
			String[] values = requestMapping.value();
			if (values != null && values.length > 0) {
				methodPath = values[0];
				if (!"".equals(methodPath) && !methodPath.startsWith("/"))
					methodPath = "/" + methodPath;
			}
		}
		return classPath + methodPath;
	}

	private String getPermissionSn(String value) {
		String regex = "\\[(.*?)]";
		Pattern p = Pattern.compile("(?<=\\()[^\\)]+");
		Matcher m = p.matcher(value);
		String permissionSn = null;
		if (m.find()) {
			permissionSn = m.group(0).substring(1, m.group().length() - 1);
		}
		return permissionSn;
	}

	public static void main(String[] args) {
		String regex = "\\[(.*?)]";
		String text = "hasAuthority('permission:add')";
		Pattern p = Pattern.compile("(?<=\\()[^\\)]+");
		Matcher m = p.matcher(text);
		if (m.find()) {
			System.out.println(m.group(0).substring(1, m.group().length() - 1));
		}
	}
}

